home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
lisp
/
kcl
/
akcl
/
akcl1615.lha
/
mp
/
mp2.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-02-13
|
10KB
|
620 lines
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*~ ~*/
/*~ OPERATIONS DE BASE (NOYAU) ~*/
/*~ Functions which can be efficient in plain C ~*/
/*~ ~*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#include "config.h"
#include "genpari.h"
#include "arith.h"
/* -2147483648 */
ulong MOST_NEGS[3]={0x01ff0003, 0xff000003,1<<31};
/* +2147483648 */
ulong ABS_MOST_NEGS[3]={0x01ff0003, 0x01000003,1<<31};
GEN stoi(x)
long x;
{
GEN y;
if(!x) return gzero;
y=cgeti(3);
if(x>0) {y[1]=0x1000003;y[2]=x;}
else{y[1]=0xff000003;y[2]= -x;}
return y;
}
GEN cgetg(x,y)
long x,y;
{
unsigned long p1;
GEN z;
p1=avma-(((unsigned short)x)<<2);if(p1<bot) err(errpile);
avma=p1;z=(GEN)p1;z[0]=0x10000+x+(y<<24);
return z;
}
GEN cgeti(x)
long x;
{
unsigned long p1;
GEN z;
p1=avma-4*x;if(p1<bot) err(errpile);
avma=p1;z=(GEN)p1;z[0]=0x1010000+x;
return z;
}
GEN icopy(x)
GEN x;
{
GEN y;
long lx=lgef(x),i;
y=cgeti(lx);
for(i=1;i<lx;i++) y[i]=x[i];
return y;
}
GEN negi(x)
GEN x;
{
long s=signe(x);
GEN y;
if(!s) return gzero;
y=icopy(x);setsigne(y,-s);
return y;
}
GEN absi(x)
GEN x;
{
GEN y;
long s=signe(x);
if(!s) return gzero;
y=icopy(x);setsigne(y,1);return y;
}
long itos(x)
GEN x;
{
long s=signe(x),p2;
unsigned long p1;
if(!s) return 0;
if(lgef(x)>3) err(affer2);
p1=x[2];if(p1>=0x80000000) err(affer2);
p2=(s>0)?p1:(-((long)p1));return p2;
}
void affsi(s,x)
long s;
GEN x;
{
long lx;
if(!s) {x[1]=2;return;}
lx=lg(x);if(lx<3) err(affer1);
if(s>0) {x[1]=0x1000003;x[2]=s;}
else { s = -s;
if (s < 0) /* s = -2^31 */
{ if(lx<4) err(affer1);
x[1]=0xff000004;
x[2]= 0;
x[3]= 1;
}
else
{x[1]=0xff000003;x[2]= s;}
}
}
void affii(x,y)
GEN x,y;
{
long lx=lgef(x),i;
if(x==y) return;
if(lg(y)<lx) err(affer3);
for(i=1;i<lx;i++) y[i]=x[i];
}
GEN shifts(x,y)
long x,y;
{
long t[3];
if(!x) return gzero;
t[0]=0x1010003;
if(x>0) {t[1]=0x1000003;t[2]=x;}
else {t[1]=0xff000003;t[2]= -x;}
return shifti(t,y);
}
GEN shifti(x,n)
GEN x;
long n;
{
long lx=lgef(x),i,s=signe(x),d,m,p1,p2,k;
GEN y; TEMPVARS
ulong hiremainder;
if(!s) return gzero;
if(!n) return icopy(x);
if(n>0)
{
d=n>>5;m=n&31;
if(m)
{
p1=shiftl(x[2],m);p2=hiremainder;k=0;
if(p2)
{
y=cgeti(lx+d+1);for(i=lx+1;i<=lx+d;i++) y[i]=0;
for(i=lx;i>=4;i--) {y[i]=shiftl(x[i-1],m)+k;k=hiremainder;}
y[3]=p1+k;y[2]=p2;
}
else
{
y=cgeti(lx+d);for(i=lx;i<lx+d;i++) y[i]=0;
for(i=lx-1;i>=3;i--) {y[i]=shiftl(x[i],m)+k;k=hiremainder;}
y[2]=p1+k;
}
}
else
{
y=cgeti(lx+d);for(i=lx;i<lx+d;i++) y[i]=0;
for(i=lx-1;i>=2;i--) y[i]=x[i];
}
}
else
{
n= -n;d=n>>5;m=n&31;if(lx<d+3) return gzero;
if(!m)
{
y=cgeti(lx-d);for(i=2;i<lx-d;i++) y[i]=x[i];
}
else
{
m=32-m;d++;
p1=shiftl(x[2],m);
if(hiremainder)
{
y=cgeti(lx-d+1);y[2]=hiremainder;
for(i=3;i<=lx-d;i++)
{
p2=shiftl(x[i],m);y[i]=p1+hiremainder;p1=p2;
}
}
else
{
if(lx==d+2) return gzero;
y=cgeti(lx-d);
for(i=3;i<=lx-d;i++)
{
p2=shiftl(x[i],m);y[i-1]=p1+hiremainder;p1=p2;
}
}
}
}
y[1]=y[0];setsigne(y,s);return y;
}
GEN mptrunc(x)
GEN x;
{
long e,i,s,lx=lg(x),p1,p2,m;
unsigned long d; TEMPVARS
GEN y;ulong hiremainder;
if(typ(x)==1) return icopy(x);
s=signe(x);if(!s) return gzero;
e=expo(x);if(e<0) return gzero;
d=e>>5;m=e&31;if(d>=lx-2) err(truer2);
y=cgeti(d+3);y[1]=y[0];setsigne(y,s);
if(m==31) for(i=2;i<=d+2;i++) y[i]=x[i];
else
{
m++;p1=0;
for(i=2;i<=d+2;i++)
{
p2=shiftl(x[i],m);y[i]=hiremainder+p1;p1=p2;
}
}
return y;
}
GEN mpent(x)
GEN x;
{
long e,i,lx=lg(x),m,f,p1,p2;
unsigned long d;ulong hiremainder;
GEN y,z; TEMPVARS
if(typ(x)==1) return icopy(x);
if(signe(x)>=0) return mptrunc(x);
e=expo(x);if(e<0) {y=cgeti(3);y[2]=1;y[1]=0xff000003;return y;}
d=e>>5;m=e&31;if(d>=lx-2) err(truer2);
y=cgeti(d+3);y[1]=0xff000003+d;
if(m==31)
{
for(i=2;i<=d+2;i++) y[i]=x[i];
while((i<lx)&&(!x[i])) i++;
f=(i<lx);
}
else
{
m++;p1=0;
for(i=2;i<=d+2;i++)
{
p2=shiftl(x[i],m);y[i]=hiremainder+p1;p1=p2;
}
if(p1) f=1;
else
{
while((i<lx)&&(!x[i])) i++;
f=(i<lx);
}
}
if(f)
{
for(i=d+2;(i>=2)&&(y[i]==0xffffffff);i--) y[i]=0;
if(i>=2) y[i]++;
else
{
z=y;y=cgeti(1);*y=(*z)+1;y[1]=z[1]+1;
}
}
return y;
}
int cmpsi(x,y)
long x;
GEN y;
{
ulong p;
if(!x) return -signe(y);
if(x>0)
{
if(signe(y)<=0) return 1;
if(lgef(y)>3) return -1;
p=y[2];if(p==x) return 0;
return (p<(ulong)x) ? 1 : -1;
}
else
{ /* x <= 0 */
if(signe(y)>=0) return -1;
if(lgef(y)>3)
{ if (-x < 0)
{ /* x = -2^31 */
if (lgef(y)==4 &&
y[2] == 0 &&
y[3] == 1)
return 0;
else
return 1;}}
p=y[2];if(p== -x) return 0;
return (p<(ulong)(-x)) ? -1 : 1;
}
}
int cmpii(x,y)
GEN x,y;
{
long sx=signe(x),sy=signe(y),lx,ly,i;
if(sx<sy) return -1;
if(sx>sy) return 1;
if(!sx) return 0;
lx=lgef(x);ly=lgef(y);
if(lx>ly) return sx;
if(lx<ly) return -sx;
for(i=2;(i<lx)&&(x[i]==y[i]);i++);
if(i==lx) return 0;
return ((ulong)x[i]>(ulong)y[i]) ? sx : -sx;
}
GEN addss(x,y)
long x,y;
{
long t[3];
if(!x) return stoi(y);
t[0]=0x1010003;
if(x>0) {t[1]=0x1000003;t[2]=x;} else {t[1]=0xff000003;t[2]= -x;}
return addsi(y,t);
}
GEN subii(x,y)
GEN x,y;
{
long s=signe(y);
GEN z;
if(x==y) return gzero;
setsigne(y,-s);z=addii(x,y);setsigne(y,s);
return z;
}
GEN subsi(x,y)
long x;
GEN y;
{
long s=signe(y);
GEN z;
setsigne(y,-s);z=addsi(x,y);setsigne(y,s);return z;
}
GEN subss(x,y)
long x,y;
{
if (y == (1<<31))
return addsi(x,ABS_MOST_NEGS);
return addss(-y,x);
}
GEN convi(x)
GEN x;
{
long lx,av=avma,lz;
GEN z,p1,p2;
if(!signe(x))
{
z=cgeti(3);z[1]= -1;z[2]=0;avma=av;return z+3;
}
p1=absi(x);lx=lgef(p1);lz=((lx-2)*15)/14+3;z=cgeti(lz);z[1]= -1;
for(p2=z+2;signe(p1);p2++) *p2=divisii(p1,1000000000,p1);
avma=av;return p2;
}
void mulsii(x,y,z)
long x;
GEN y,z;
{
long av=avma;
GEN p1;
p1=mulsi(x,y);affii(p1,z);avma=av;
}
void addsii(x,y,z)
long x;
GEN y,z;
{
long av=avma;
GEN p1;
p1=addsi(x,y);affii(p1,z);avma=av;
}
long divisii(x,y,z)
long y;
GEN x,z;
{
long av=avma,k;
GEN p1;
p1=divis(x,y);affii(p1,z);avma=av;
k=hiremainder;return k;
}
long vals(x)
long x;
{
unsigned short int y,z;
int s;
if(!x) return -1;
y=x;if(!y) {s=16;y=((ulong)x)>>16;} else s=0;
z=y&255;if(!z) {s+=8;z=y>>8;}
y=z&15;if(!y) {s+=4;y=z>>4;}
z=y&3;if(!z) {s+=2;z=y>>2;}
return (z&1) ? s : s+1;
}
long vali(x)
GEN x;
{
long i,lx=lgef(x);
if(!signe(x)) return -1;
for(i=lx-1;(i>=2)&&(!x[i]);i--);
return ((lx-1-i)<<5)+vals(x[i]);
}
GEN dvmdss(x,y,z)
long x,y;
GEN *z;
{
GEN p1;
p1=divss(x,y);*z=stoi(hiremainder);
return p1;
}
GEN dvmdsi(x,y,z)
long x;
GEN y,*z;
{
GEN p1;
p1=divsi(x,y);*z=stoi(hiremainder);
return p1;
}
GEN dvmdis(x,y,z)
long y;
GEN x,*z;
{
GEN p1;
p1=divis(x,y);*z=stoi(hiremainder);
return p1;
}
GEN ressi(x,y)
long x;
GEN y;
{
divsi(x,y);return stoi(hiremainder);
}
GEN modsi(x,y)
long x;
GEN y;
{
long s;
GEN p1;
divsi(x,y);
if(!hiremainder) return gzero;
if(x>0) return stoi(hiremainder);
else
{
s=signe(y);setsigne(y,1);p1=addsi(hiremainder,y);
setsigne(y,s);return p1;
}
}
GEN modis(x,y)
long y;
GEN x;
{
divis(x,y);if(!hiremainder) return gzero;
return (signe(x)>0) ? stoi(hiremainder) : stoi(abs(y)+hiremainder);
}
GEN resis(x,y)
long y;
GEN x;
{
divis(x,y);return stoi(hiremainder);
}
GEN modii(x,y)
GEN x,y;
{
long av=avma,tetpil;
GEN p1;
p1=dvmdii(x,y,-1);
if(signe(p1)>=0) return p1;
tetpil=avma;p1=(signe(y)>0) ? addii(p1,y) : subii(p1,y);
return gerepile(av,tetpil,p1);
}
mpdivis(x,y,z)
GEN x,y,z;
{
long av=avma;
GEN p1,p2;
p1=dvmdii(x,y,&p2);
if(signe(p2)) {avma=av;return 0;}
affii(p1,z);avma=av;return 1;
}
divise(x,y)
GEN x,y;
{
long av=avma;
GEN p1;
p1=dvmdii(x,y,-1);avma=av;
return signe(p1) ? 0 : 1;
}
GEN gerepile(l,p,q)
GEN l,p,q;
{
long av,declg,tl;
GEN ll,pp,l1,l2,l3;
declg=(long)l-(long)p;if(declg<=0) return q;
for(ll=l,pp=p;pp>(GEN)avma;) *--ll= *--pp;
av=(long)ll;
while((ll<l)||((ll==l)&&(long)q))
{
l2=ll+lontyp[tl=typ(ll)];
if(tl==10) {l3=ll+lgef(ll);ll+=lg(ll);if(l3>ll) l3=l2;}
else {ll+=lg(ll);l3=ll;}
for(;l2<l3;l2++)
/* for(;l2<ll;l2++) */
{
l1=(GEN)(*l2);
if((l1<l)&&(l1>=(GEN)avma))
{
if(l1<p) *l2+=declg;
else
if(ll<=l) err(gerper);
}
}
}
if((!((long)q))||((q<p)&&(q>=(GEN)avma)))
{
avma=av;return q+(declg>>2);
}
else {avma=av;return q;}
}
void cgiv(x)
GEN x;
{
long p;
if((p=pere(x))==255) return;
if((x!=(GEN)avma)||(p>1)) {setpere(x,p-1);return;}
do x+=lg(x);while(!pere(x));
avma=(long)x;
return;
}